package com.mininglamp.hbga.util;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.mininglamp.hbga.adapter.Adapter;
import com.mininglamp.hbga.adapter.BaseAdapter;
import org.javatuples.Triplet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 适配器工具类
 * Created by kevin on 2017/8/6.
 */
public class AdapterHelper {

    private static final Logger logger = LoggerFactory.getLogger(AdapterHelper.class);

    public static final AdapterHelper INSTANCE = new AdapterHelper();

    // adapter name, desc and class
    private List<Triplet<String, String, Class<BaseAdapter>>> adapters = Lists.newArrayList();

    private AdapterHelper() {
        load();
    }

    private void load() {
        adapters.addAll(
            Splitter.on(';').omitEmptyStrings().trimResults().splitToList(
                ConfigHelper.INSTANCE.getProperty("api.router.adapter.scan")
            ).stream().flatMap(p ->
                ClassUtil.getClasses(p).stream()
            ).filter(c ->
                BaseAdapter.class.isAssignableFrom(c) && c.getAnnotation(Adapter.class) != null
            ).map(c -> {
                Adapter anno = c.getAnnotation(Adapter.class);
                logger.info("加载适配器成功：name = {}, desc = {}, adapter = {}", anno.name(), anno.desc(), c);

                return Triplet.with(anno.name(), anno.desc(), (Class<BaseAdapter>) c);
            }).collect(Collectors.toList())
        );
    }

    /**
     * 根据名称获取适配器实例
     *
     * @param adapterName
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public BaseAdapter adapterClass(String adapterName) /*throws IllegalAccessException, InstantiationException*/ {
        try {
            return adapters.stream().filter(
                t -> adapterName.equals(t.getValue0())
            ).map(
                t -> t.getValue2()
            ).findFirst().get().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取所有适配器信息
     *
     * @return
     */
    public List<Map<String, Object>> adapters() {
        return adapters.stream().map(t -> new HashMap<String, Object>() {
            {
                put("AdapterName", t.getValue0());
                put("AdapterDesc", t.getValue1());
                put("AdapterClass", t.getValue2());
            }
        }).collect(Collectors.toList());
    }

}
